home *** CD-ROM | disk | FTP | other *** search
/ T&A 2 the Maxx 3 / T and A 2 The Maxx Number 3.iso / viewers / unixview / xgiftar.z / xgiftar / fbm.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  7KB  |  283 lines

  1. /*
  2.  * fbm.c:
  3.  *
  4.  * adapted from code by Michael Mauldin, (mlm) at Carnegie-Mellon
  5.  * University, (fbm tools) and Kirk L. Johnson, (tuna@athena.mit.edu),
  6.  * (gif.c).
  7.  *
  8.  * fbmin.c
  9.  * Mark Majhor
  10.  * August 1990
  11.  *
  12.  * routines for reading FBM files
  13.  *
  14.  * Copyright 1990 Mark Majhor (see the included file
  15.  * "mrmcpyrght.h" for complete copyright information)
  16.  */
  17. # include <stdio.h>
  18. # include <math.h>
  19. # include <ctype.h>
  20. # include "image.h"
  21. # include "fbm.h"
  22.  
  23. /****
  24.  **
  25.  ** local variables
  26.  **
  27.  ****/
  28.  
  29. static BYTE file_open = 0;    /* status flags */
  30. static BYTE image_open = 0;
  31.  
  32. static ZFILE *ins;        /* input stream */
  33. static FBMFILEHDR phdr;        /* header structure */
  34.  
  35. /****
  36.  **
  37.  ** global variables
  38.  **
  39.  ****/
  40.  
  41. static int  fbmin_img_width;           /* image width */
  42. static int  fbmin_img_height;          /* image height */
  43. static int  fbmin_img_depth;           /* image depth */
  44. static int  fbmin_img_bits;           /* color bits */
  45. static int  fbmin_img_rowlen;           /* length of one row of data */
  46. static int  fbmin_img_plnlen;           /* length of one plane of data */
  47. static int  fbmin_img_clrlen;           /* length of the colormap */
  48. static int  fbmin_img_aspect;           /* image aspect ratio */
  49. static int  fbmin_img_physbits;           /* physical bits per pixel */
  50. static char *fbmin_img_title;        /* name of image */
  51. static char *fbmin_img_credit;        /* credit for image */
  52.  
  53. /*
  54.  * open FBM image in the input stream; returns FBMIN_SUCCESS if
  55.  * successful. (might also return various FBMIN_ERR codes.)
  56.  */
  57. static int fbmin_open_image(s)
  58. ZFILE *s;
  59. {
  60.   char *hp;        /* header pointer */
  61.  
  62.   /* make sure there isn't already a file open */
  63.   if (file_open)
  64.     return(FBMIN_ERR_FAO);
  65.  
  66.   /* remember that we've got this file open */
  67.   file_open = 1;
  68.   ins = s;
  69.  
  70.   /* read in the fbm file header */
  71.   hp = (char *) &phdr;
  72.   if (zread(ins, (byte *)hp, sizeof(phdr)) != sizeof(phdr))
  73.     return FBMIN_ERR_EOF;
  74.  
  75.   if (strncmp(FBM_MAGIC, phdr.magic, sizeof(FBM_MAGIC)) != 0)
  76.     return FBMIN_ERR_BAD_SIG;
  77.  
  78.   /* Now extract relevant features of FBM file header */
  79.   fbmin_img_width    = atoi(phdr.cols);
  80.   fbmin_img_height   = atoi(phdr.rows);
  81.   fbmin_img_depth    = atoi(phdr.planes);
  82.   fbmin_img_bits     = atoi(phdr.bits);
  83.   fbmin_img_rowlen   = atoi(phdr.rowlen);
  84.   fbmin_img_plnlen   = atoi(phdr.plnlen);
  85.   fbmin_img_clrlen   = atoi(phdr.clrlen);
  86.   fbmin_img_aspect   = atoi(phdr.aspect);
  87.   fbmin_img_physbits = atoi(phdr.physbits);
  88.   fbmin_img_title    = phdr.title;
  89.   fbmin_img_credit   = phdr.credits;
  90.  
  91.   if (fbmin_image_test() != FBMIN_SUCCESS)
  92.     return FBMIN_ERR_BAD_SD;
  93.  
  94.   return FBMIN_SUCCESS;
  95. }
  96.  
  97. /*
  98.  * close an open FBM file
  99.  */
  100.  
  101. static int fbmin_close_file()
  102. {
  103.   /* make sure there's a file open */
  104.   if (!file_open)
  105.     return FBMIN_ERR_NFO;
  106.  
  107.   /* mark file (and image) as closed */
  108.   file_open  = 0;
  109.   image_open = 0;
  110.  
  111.   /* done! */
  112.   return FBMIN_SUCCESS;
  113. }
  114.     
  115. static fbmin_image_test()
  116. {
  117.   if (fbmin_img_width < 1 || fbmin_img_width > 32767) {
  118.     fprintf (stderr, "Invalid width (%d) on input\n", fbmin_img_width);
  119.     return FBMIN_ERR_BAD_SD;
  120.   }
  121.  
  122.   if (fbmin_img_height < 1 || fbmin_img_height > 32767) {
  123.     fprintf (stderr, "Invalid height (%d) on input\n", fbmin_img_height);
  124.     return (0);
  125.   }
  126.  
  127.   if (fbmin_img_depth != 1 && fbmin_img_depth != 3) {
  128.     fprintf (stderr, "Invalid number of planes (%d) on input %s\n",
  129.          fbmin_img_depth, "(must be 1 or 3)");
  130.     return FBMIN_ERR_BAD_SD;
  131.   }
  132.  
  133.   if (fbmin_img_bits < 1 || fbmin_img_bits > 8) {
  134.     fprintf (stderr, "Invalid number of bits (%d) on input %s\n",
  135.          fbmin_img_bits, "(must be [1..8])");
  136.     return FBMIN_ERR_BAD_SD;
  137.   }
  138.  
  139.   if (fbmin_img_physbits != 1 && fbmin_img_physbits != 8) {
  140.     fprintf (stderr, "Invalid number of physbits (%d) on input %s\n",
  141.          fbmin_img_physbits, "(must be 1 or 8)");
  142.     return FBMIN_ERR_BAD_SD;
  143.   }
  144.  
  145.   if (fbmin_img_rowlen < 1 || fbmin_img_rowlen > 32767) {
  146.     fprintf (stderr, "Invalid row length (%d) on input\n",
  147.          fbmin_img_rowlen);
  148.     return FBMIN_ERR_BAD_SD;
  149.   }
  150.  
  151.   if (fbmin_img_depth > 1 && fbmin_img_plnlen < 1) {
  152.     fprintf (stderr, "Invalid plane length (%d) on input\n",
  153.          fbmin_img_plnlen);
  154.     return FBMIN_ERR_BAD_SD;
  155.   }
  156.  
  157.   if (fbmin_img_aspect < 0.01 || fbmin_img_aspect > 100.0) {
  158.     fprintf (stderr, "Invalid aspect ratio %lg on input\n",
  159.          fbmin_img_aspect);
  160.     return FBMIN_ERR_BAD_SD;
  161.   }
  162.     return FBMIN_SUCCESS;
  163. }
  164.  
  165. #if 0
  166. /*
  167.  * semi-graceful fatal error mechanism
  168.  */
  169.  
  170. static fbmin_fatal(msg)
  171.      char *msg;
  172. {
  173.   printf("Error reading FBM file: %s\n", msg);
  174.   exit(0);
  175. }
  176. #endif
  177.  
  178. /*
  179.  * these are the routines added for interfacing to xloadimage
  180.  */
  181.  
  182. /*
  183.  * tell someone what the image we're loading is.  this could be a little more
  184.  * descriptive but I don't care
  185.  */
  186.  
  187. static void tellAboutImage(name)
  188.      char *name;
  189. {
  190.   printf("%s is a %dx%d FBM image with %d colors\n", name,
  191.     fbmin_img_width, fbmin_img_height, fbmin_img_clrlen / 3);
  192. }
  193.  
  194. Image *fbmLoad(fullname, name, verbose)
  195.      char         *fullname, *name;
  196.      unsigned int  verbose;
  197.   ZFILE *zf;
  198.   Image *image;
  199.   register int    x, y, j, k, rowlen, plnlen;
  200.   unsigned char *pixptr, *cm;
  201.   extern int Scrn;
  202.   unsigned char *r, *g, *b;
  203.  
  204.   if (! (zf= zopen(fullname)))
  205.     return(NULL);
  206.   if (fbmin_open_image(zf) != FBMIN_SUCCESS) {  /* read image header */
  207.     fbmin_close_file();
  208.     zclose(zf);
  209.     return(NULL);
  210.   }
  211.   if (verbose)
  212.     tellAboutImage(name);
  213.   znocache(zf);
  214.  
  215.   image = newRGBImage(fbmin_img_width, fbmin_img_height, fbmin_img_bits);
  216.  
  217.   /* if image has a local colormap, override global colormap
  218.    */
  219.   if (fbmin_img_clrlen > 0) {
  220.     cm = (unsigned char *) lmalloc(fbmin_img_clrlen);
  221.  
  222.     if (zread(ins, cm, fbmin_img_clrlen) != fbmin_img_clrlen) {
  223.       fprintf (stderr, "can't read colormap (%d bytes)\n", fbmin_img_clrlen);
  224.       return(NULL);
  225.     }
  226.     /*
  227.      * fbm color map is organized as
  228.      * buf[3][16]
  229.      */
  230.     y = fbmin_img_clrlen / 3;
  231.     r = &cm[0], g = &cm[y], b = &cm[2 * y];
  232.     for (x = 0; x < y; x++, r++, g++, b++) {
  233.       image->rgb.red[x]   = *r << 8;
  234.       image->rgb.green[x] = *g << 8;
  235.       image->rgb.blue[x]  = *b << 8;
  236.     }
  237.     image->rgb.used = y;
  238.  
  239.   } else
  240.     cm = NULL;
  241.  
  242.   rowlen = fbmin_img_rowlen;
  243.   plnlen = fbmin_img_plnlen;
  244.  
  245.   for (k = 0; k < fbmin_img_depth; k++) {
  246.     pixptr = &(image->data[k * plnlen]);
  247.  
  248.     for (j = 0; j < fbmin_img_height; j++, pixptr += rowlen) {
  249.       if (zread(ins, pixptr, rowlen) != rowlen) {
  250.     printf("%s: Short read within image data\n", fullname);
  251.         exit(1);
  252.       }
  253.     }
  254.   }
  255.  
  256.   if (cm != NULL)
  257.     lfree(cm);
  258.  
  259.   fbmin_close_file();
  260.   zclose(zf);
  261.   image->title= dupString(name);
  262.   return(image);
  263. }
  264.  
  265. int fbmIdent(fullname, name)
  266. char *fullname, *name;
  267. {
  268.   ZFILE        *zf;
  269.   unsigned int  ret;
  270.  
  271.   if (! (zf= zopen(fullname)))
  272.     return(0);
  273.   if (fbmin_open_image(zf) == FBMIN_SUCCESS) {
  274.     tellAboutImage(name);
  275.     ret = 1;
  276.   } else
  277.     ret = 0;
  278.   fbmin_close_file();
  279.   zclose(zf);
  280.   return(ret);
  281. }
  282.